<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

	<xsl:template match="HeaderInfo">

using System;
using System.Collections.Generic;
using System.Text;
using System.Web;
using System.Runtime.Remoting.Messaging;


namespace <xsl:value-of select="ProjectName"/>.Data.NHibernateDal
{
	<![CDATA[
	/// <summary>
	/// NHibernate Session Management - Provides the bridge between
	/// your application and NHibernate to the DAL
	/// </summary>
	public sealed class SessionManager
	{

		private NHibernate.ISessionFactory _session;

		private void Init ( )
		{
			try
			{
				_session = new NHibernate.Cfg.Configuration ( ).Configure ( ).BuildSessionFactory ( );
			}
			catch ( Exception ex )
			{
				Console.Error.WriteLine ( ex.Message );
				while ( ex.InnerException != null )
				{
					Console.Error.WriteLine ( ex.Message );
					ex = ex.InnerException;
				}
				throw ex;
			}
		}


		#region SessionManager Singleton Managment

		// Singleton implementation (thread safe - see http://www.yoda.arachsys.com/csharp/singleton.html)
		public static SessionManager Instance
		{
			get
			{
				return Nested.SessionManager;
			}
		}


		private SessionManager() {
		    Init();
		}


		/// <summary>
		/// Assists with ensuring thread-safe, lazy singleton
		/// </summary>
		private class Nested
		{
			static Nested ( ) { }
			internal static readonly SessionManager SessionManager =
				new SessionManager ( );
		}

		#endregion


		#region NHibernate Session Management

		public NHibernate.ISession GetSession ( )
		{
			return GetSession ( null );
		}

		/// <summary>
		/// Gets a session with or without an interceptor.  This method is not called directly; instead,
		/// it gets invoked from other public methods.
		/// </summary>
		private NHibernate.ISession GetSession ( NHibernate.IInterceptor interceptor )
		{
			NHibernate.ISession session = ContextSession;

			if ( session == null )
			{
				if ( interceptor != null )
				{
					session = _session.OpenSession ( interceptor );
				}
				else
				{
					session = _session.OpenSession ( );
				}

				ContextSession = session;
			}

			return session;
		}

		/// <summary>
		/// Flushes anything left in the session and closes the connection.
		/// </summary>
		public void CloseSession ( )
		{
			NHibernate.ISession session = ContextSession;

			if ( session != null && session.IsOpen )
			{
				session.Flush ( );
				session.Close ( );
			}

			ContextSession = null;
		}

		public void BeginTransaction ( )
		{
			NHibernate.ITransaction transaction = ContextTransaction;

			if ( transaction == null )
			{
				transaction = GetSession ( ).BeginTransaction ( );
				ContextTransaction = transaction;
			}
		}

		public void CommitTransaction ( )
		{
			NHibernate.ITransaction transaction = ContextTransaction;

			try
			{
				if ( HasOpenTransaction ( ) )
				{
					transaction.Commit ( );
					ContextTransaction = null;
				}
			}
			catch ( NHibernate.HibernateException )
			{
				RollbackTransaction ( );
				throw;
			}
		}

		public bool HasOpenTransaction ( )
		{
			NHibernate.ITransaction transaction = ContextTransaction;

			return transaction != null && !transaction.WasCommitted && !transaction.WasRolledBack;
		}

		public void RollbackTransaction ( )
		{
			NHibernate.ITransaction transaction = ContextTransaction;

			try
			{
				if ( HasOpenTransaction ( ) )
				{
					transaction.Rollback ( );
				}

				ContextTransaction = null;
			}
			finally
			{
				CloseSession ( );
			}
		}


		/// <summary>
		/// Uses different context based on type of application
		/// </summary>
		private NHibernate.ITransaction ContextTransaction
		{
			get
			{
				if ( IsInWebContext ( ) )
				{
					return ( NHibernate.ITransaction ) HttpContext.Current.Items[ TRANSACTION_KEY ];
				}
				else
				{
					return ( NHibernate.ITransaction ) CallContext.GetData ( TRANSACTION_KEY );
				}
			}
			set
			{
				if ( IsInWebContext ( ) )
				{
					HttpContext.Current.Items[ TRANSACTION_KEY ] = value;
				}
				else
				{
					CallContext.SetData ( TRANSACTION_KEY , value );
				}
			}
		}

		/// <summary>
		/// Uses HttpContext for web based NHibernate DAL
		/// </summary>
		private NHibernate.ISession ContextSession
		{
			get
			{
				if ( IsInWebContext ( ) )
				{
					return ( NHibernate.ISession ) HttpContext.Current.Items[ SESSION_KEY ];
				}
				else
				{
					return ( NHibernate.ISession ) CallContext.GetData ( SESSION_KEY );
				}
			}
			set
			{
				if ( IsInWebContext ( ) )
				{
					HttpContext.Current.Items[ SESSION_KEY ] = value;
				}
				else
				{
					CallContext.SetData ( SESSION_KEY , value );
				}
			}
		}


		/// <summary>
		/// Detects if the application is within the web context.
		/// </summary>
		/// <returns></returns>
		private bool IsInWebContext ( )
		{
			return HttpContext.Current != null;
		}

		private const string TRANSACTION_KEY = "CONTEXT_TRANSACTION";
		private const string SESSION_KEY = "CONTEXT_SESSION";

		#endregion


	}]]>
}

	</xsl:template>
</xsl:stylesheet>